package com.link2room.soundwave.facade.impl;

import com.link2room.common.constant.DefaultValue;
import com.link2room.common.dto.param.base.BaseL2rParamDto;
import com.link2room.common.dto.param.base.BaseParamDto;
import com.link2room.common.jpa.result.QueryResult;
import com.link2room.common.service.ICommonService;
import com.link2room.common.util.L2RAssert;
import com.link2room.enums.exception.SoundwaveSysExceptionEnum;
import com.link2room.soundwave.constant.L2RPointConstant;
import com.link2room.soundwave.dto.param.inside.*;
import com.link2room.soundwave.dto.result.base.PmsCardPointDto;
import com.link2room.soundwave.dto.result.base.PmsCouponDto;
import com.link2room.soundwave.dto.result.base.PmsPackageDto;
import com.link2room.soundwave.entity.L2RPmsCoupon;
import com.link2room.soundwave.entity.PmsCouponSale;
import com.link2room.soundwave.entity.PmsPackageSale;
import com.link2room.soundwave.entity.PmsPointDetail;
import com.link2room.soundwave.exception.SoundwaveException;
import com.link2room.soundwave.dto.result.base.PmsMemberInfoDto;
import com.link2room.soundwave.facade.IPmsMemberHandlerFacadeService;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;

/**
 * Created by VegetaKo on 2016/9/18.
 */
public abstract class AbstractPmsMemberHandlerFacadeServiceImpl implements IPmsMemberHandlerFacadeService {

    abstract PmsMemberInfoDto checkPMSMember(MemberLoginInsideParamDto memberLoginParamDto) throws Exception;

    abstract PmsMemberInfoDto bindingPMSMember(MemberLoginInsideParamDto memberLoginParamDto) throws Exception;

    abstract void unbindingPMSMember(MemberLoginInsideParamDto memberLoginParamDto) throws Exception;

    abstract QueryResult<PmsCouponDto> getPmsMemberCoupons(MemberLoginInsideParamDto memberLoginParamDto) throws Exception;

    abstract void checkRegister(MemberLoginInsideParamDto memberLoginInsideParamDto) throws Exception;

    abstract PmsMemberInfoDto newPMSMember(MemberLoginInsideParamDto memberLoginInsideParamDto) throws Exception;

    abstract com.link2room.soundwave.dto.result.base.PmsMemberPointDto getPmsMemberPoints(MemberLoginInsideParamDto memberLoginParamDto) throws Exception;

    abstract void presentPoint(PointPresentUseInsideParamDto pointPresentUseInsideParamDto) throws Exception;

    abstract void usePoint(PointPresentUseInsideParamDto pointPresentUseInsideParamDto) throws Exception;

    abstract List<PmsCardPointDto> getPmsMemberPointsDetail(MemberLoginInsideParamDto memberLoginParamDto) throws Exception;

    abstract PmsMemberInfoDto autoMember(MemberLoginInsideParamDto memberLoginInsideParamDto ) throws Exception;

    abstract PmsMemberInfoDto syncMember(MemberLoginInsideParamDto memberLoginInsideParamDto ) throws Exception;

    abstract com.link2room.soundwave.dto.result.base.PmsCardBalanceDto getCardBalanceInfo (MemberLoginInsideParamDto memberLoginInsideParamDto ) throws Exception;

    abstract QueryResult<PmsCouponDto> getUsableCoupons(UsableCouopnsInsideParamDto usableCouopnsInsideParamDto) throws Exception;

    abstract PmsMemberInfoDto getCurrentUserPMSMemberInfo(BaseL2rParamDto paramDto) throws Exception;

    abstract String onlineSaleCoupon(UsableCouopnsInsideParamDto usableCouopnsInsideParamDto) throws Exception;

    abstract QueryResult<PmsPackageDto> listPmsPackage(BaseParamDto baseParamDto) throws Exception;

    abstract PmsPackageDto getPmsPackage(BaseParamDto baseParamDto) throws Exception;

    abstract void exchangePackage(MemberPackageInsideParamDto memberPackageInsideParamDto) throws Exception;

    @Resource
    private ICommonService commonService;

    abstract PmsMemberInfoDto upgradePmsMemberLevel(MemberUpgradeInsideParamDto memberUpgradeInsideParamDto) throws Exception;

    @Override
    public PmsMemberInfoDto checkPMSMemberHandler(MemberLoginInsideParamDto memberLoginParamDto) throws Exception {
        return checkPMSMember(memberLoginParamDto);
    }

    @Override
    public PmsMemberInfoDto bindingPMSMemberHandler(MemberLoginInsideParamDto memberLoginParamDto) throws Exception {
        return bindingPMSMember(memberLoginParamDto);
    }

    @Override
    public void unbindingPMSMemberHandler(MemberLoginInsideParamDto memberLoginParamDto) throws Exception {
        unbindingPMSMember(memberLoginParamDto);
    }

    @Override
    public com.link2room.soundwave.dto.result.base.PmsMemberPointDto getPmsMemberPointsHandler(MemberLoginInsideParamDto memberLoginParamDto) throws Exception {
        return getPmsMemberPoints(memberLoginParamDto);
    }

    @Override
    public QueryResult<PmsCouponDto> getPmsMemberCouponsHandler(MemberLoginInsideParamDto memberLoginParamDto) throws Exception {
        return getPmsMemberCoupons(memberLoginParamDto);
    }

    @Override
    public void checkRegisterHandler(MemberLoginInsideParamDto memberLoginInsideParamDto) throws Exception {
        checkRegister(memberLoginInsideParamDto);
    }

    @Override
    public PmsMemberInfoDto newPMSMemberHandler(MemberLoginInsideParamDto memberLoginInsideParamDto) throws Exception {
        return newPMSMember(memberLoginInsideParamDto);
    }

    @Override
    public void presentPointHandler(PointPresentUseInsideParamDto pointPresentUseInsideParamDto) throws Exception {
        String lhotelGroupCode=pointPresentUseInsideParamDto.getLhotelGroupCode();
        String l2rMemberNo=pointPresentUseInsideParamDto.getL2rMemberNo();
        BigDecimal point=pointPresentUseInsideParamDto.getPoint();
        String srcType=pointPresentUseInsideParamDto.getSrcType();
        L2RAssert.stringBlank(lhotelGroupCode,"[lhotelGroupCode] is null.");
        L2RAssert.stringBlank(l2rMemberNo,"[l2rMemberNo] is null.");
        L2RAssert.objectNull(point,"[point] is null.");
        PmsPointDetail pmsPointDetail =this.savePointDetail(lhotelGroupCode,l2rMemberNo,srcType , L2RPointConstant.OPERA_TYPE.ADD, point);
        presentPoint(pointPresentUseInsideParamDto);
        this.updatePointDetail(pmsPointDetail);
    }

    @Override
    public void usePointHandler(PointPresentUseInsideParamDto pointPresentUseInsideParamDto) throws Exception {
        String lhotelGroupCode=pointPresentUseInsideParamDto.getLhotelGroupCode();
        String l2rMemberNo=pointPresentUseInsideParamDto.getL2rMemberNo();
        BigDecimal point=pointPresentUseInsideParamDto.getPoint();
        String srcType=pointPresentUseInsideParamDto.getSrcType();
        L2RAssert.stringBlank(lhotelGroupCode,"[lhotelGroupCode] is null.");
        L2RAssert.stringBlank(l2rMemberNo,"[l2rMemberNo] is null.");
        L2RAssert.objectNull(point,"[point] is null.");
        PmsPointDetail pmsPointDetail =this.savePointDetail(lhotelGroupCode,l2rMemberNo,srcType , L2RPointConstant.OPERA_TYPE.USE, point);
        usePoint(pointPresentUseInsideParamDto);
        this.updatePointDetail(pmsPointDetail);
    }

    private PmsPointDetail savePointDetail(String lhotelGroupCode, String l2rMemberNo, String srcType, String operaType, BigDecimal pointValue) throws Exception {
        PmsPointDetail pmsPointDetail=new PmsPointDetail();
        pmsPointDetail.setLhotelGroupCode(lhotelGroupCode);
        pmsPointDetail.setL2RMemberNo(l2rMemberNo);
        pmsPointDetail.setOperaType(operaType);
        pmsPointDetail.setPointValue(pointValue);
        commonService.save(pmsPointDetail);
        return pmsPointDetail;
    }

    private void updatePointDetail(PmsPointDetail pmsPointDetail) throws Exception {
        pmsPointDetail.setIsSuccess(DefaultValue.T);
        commonService.merge(pmsPointDetail);
    }

    @Override
    public List<PmsCardPointDto> getPmsMemberPointsDetailHandler(MemberLoginInsideParamDto memberLoginParamDto) throws Exception {
       return getPmsMemberPointsDetail(memberLoginParamDto);
    }

    @Override
    public PmsMemberInfoDto autoMemberHandler(MemberLoginInsideParamDto memberLoginInsideParamDto) throws Exception {
        return autoMember(memberLoginInsideParamDto);
    }

    @Override
    public PmsMemberInfoDto syncMemberHandler(MemberLoginInsideParamDto memberLoginInsideParamDto) throws Exception {
        return syncMember(memberLoginInsideParamDto);
    }

    @Override
    public com.link2room.soundwave.dto.result.base.PmsCardBalanceDto getCardBalanceInfoHandler(MemberLoginInsideParamDto memberLoginInsideParamDto) throws Exception {
        return getCardBalanceInfo(memberLoginInsideParamDto);
    }

    @Override
    public QueryResult<PmsCouponDto> getUsableCouponsHandler(UsableCouopnsInsideParamDto usableCouopnsInsideParamDto) throws Exception {
        return getUsableCoupons(usableCouopnsInsideParamDto);
    }

    @Override
    public PmsMemberInfoDto getCurrentUserPMSMemberInfoHandler(BaseL2rParamDto paramDto) throws Exception{
        return getCurrentUserPMSMemberInfo(paramDto);
    }

    /**
     * 发放电子券
     *
     * @param usableCouopnsInsideParamDto
     * @return
     * @throws Exception
     */
    @Override
    public void onlineSaleCouponHandler(UsableCouopnsInsideParamDto usableCouopnsInsideParamDto) throws Exception {
        this.onlineSaleCoupon(usableCouopnsInsideParamDto);
    }

    /**
     * 发放电子券<新>
     *
     * @param usableCouopnsInsideParamDto
     * @return
     * @throws Exception
     */
    @Override
    public void onlineSaleCouponNewHandler(UsableCouopnsInsideParamDto usableCouopnsInsideParamDto) throws Exception {
        String lhotelGroupCode=usableCouopnsInsideParamDto.getLhotelGroupCode();
        String pmsCouponCode=usableCouopnsInsideParamDto.getPmsCouponCode();
        String l2rMemberNo=usableCouopnsInsideParamDto.getL2RMemberNo();
        String saleType=usableCouopnsInsideParamDto.getSaleType();
        Integer saleNum=usableCouopnsInsideParamDto.getSaleNum();
        L2RAssert.stringBlank(lhotelGroupCode,"[lhotelGroupCode] is null.");
        L2RAssert.stringBlank(pmsCouponCode,"[pmsCouponCode] is null.");
        L2RAssert.stringBlank(l2rMemberNo,"[l2rMemberNo] is null.");
        L2RAssert.stringBlank(saleType,"[saleType] is null.");
        L2RAssert.objectNull(saleNum,"[saleNum] is null.");
        L2RPmsCoupon queryCoupon=new L2RPmsCoupon();
        queryCoupon.setLhotelGroupCode(lhotelGroupCode);
        queryCoupon.setPmsCouponCode(pmsCouponCode);
        L2RPmsCoupon l2RPmsCoupon=commonService.findOneEQ(L2RPmsCoupon.class,queryCoupon);
        Optional.ofNullable(l2RPmsCoupon).orElseThrow(()->new SoundwaveException(SoundwaveSysExceptionEnum.COUPON_MAPPING_IS_MISSING));
        usableCouopnsInsideParamDto.setPmsCouponType(l2RPmsCoupon.getPmsCouponType());
        PmsCouponSale pmsCouponSale=new PmsCouponSale();
        pmsCouponSale.setLhotelGroupCode(lhotelGroupCode);
        pmsCouponSale.setSaleType(saleType);
        pmsCouponSale.setL2RCouponType(l2RPmsCoupon.getL2RCouponType());
        pmsCouponSale.setL2RCouponTypeName(l2RPmsCoupon.getL2RCouponTypeName());
        pmsCouponSale.setL2RMemberNo(l2rMemberNo);
        pmsCouponSale.setPmsCouponCode(pmsCouponCode);
        pmsCouponSale.setPmsCouponName(l2RPmsCoupon.getPmsCouponName());
        pmsCouponSale.setSaleNum(saleNum);
        commonService.save(pmsCouponSale);
        String pmsCouponNo=this.onlineSaleCoupon(usableCouopnsInsideParamDto);
        pmsCouponSale.setIsSuccess(DefaultValue.T);
        pmsCouponSale.setPmsCouponNo(pmsCouponNo);
        commonService.merge(pmsCouponSale);
    }

    @Override
    public PmsMemberInfoDto upgradePmsMemberLevelHandler(MemberUpgradeInsideParamDto memberUpgradeInsideParamDto) throws Exception {
        return upgradePmsMemberLevel(memberUpgradeInsideParamDto);
    }

    @Override
    public QueryResult<PmsPackageDto>
    listPmsPackageHandler(BaseParamDto baseParamDto) throws Exception {
        L2RAssert.stringBlank(baseParamDto.getLhotelGroupCode(),"lhotelGroupCode is null");
        return this.listPmsPackage(baseParamDto);
    }

    @Override
    public PmsPackageDto getPmsPackageHandler(BaseParamDto baseParamDto) throws Exception {
        L2RAssert.stringBlank(baseParamDto.getLhotelGroupCode(),"lhotelGroupCode is null");
        return this.getPmsPackage(baseParamDto);
    }

    @Override
    public void exchangePackageHandler(MemberPackageInsideParamDto memberPackageInsideParamDto) throws Exception {
        String lhotelGroupCode=memberPackageInsideParamDto.getLhotelGroupCode();
        String orderNo=memberPackageInsideParamDto.getOrderNo();
        String activityCode=memberPackageInsideParamDto.getActivityCode();
        String exchangeType=memberPackageInsideParamDto.getExchangeType();
        String l2rMemberNo=memberPackageInsideParamDto.getL2rMemberNo();
        L2RAssert.stringBlank(lhotelGroupCode,"lhotelGroupCode is null");
        L2RAssert.stringBlank(orderNo,"orderNo is null");
        L2RAssert.stringBlank(activityCode,"activityCode is null");
        L2RAssert.stringBlank(exchangeType,"exchangeType is null");
        L2RAssert.stringBlank(l2rMemberNo,"l2rMemberNo is null");

        PmsPackageSale pmsPackageSale=new PmsPackageSale();
        pmsPackageSale.setLhotelGroupCode(lhotelGroupCode);
        pmsPackageSale.setOrderNo(orderNo);
        pmsPackageSale.setActivityCode(activityCode);
        pmsPackageSale.setExchangeType(exchangeType);
        pmsPackageSale.setL2RMemberNo(l2rMemberNo);
        commonService.save(pmsPackageSale);

        this.exchangePackage(memberPackageInsideParamDto);
        pmsPackageSale.setIsSuccess(DefaultValue.T);
        commonService.merge(pmsPackageSale);

    }
}
